package com.example.h9iserver.controller;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.example.h9iserver.common.Result;
import com.example.h9iserver.domain.User;
import com.example.h9iserver.domain.dto.UserDto;
import com.example.h9iserver.domain.query.LoginQuery;
import com.example.h9iserver.service.UserService;
import io.swagger.v3.oas.annotations.Operation;
import jakarta.servlet.Filter;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
import jakarta.servlet.http.HttpSession;
import lombok.AllArgsConstructor;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.apache.ibatis.annotations.Param;
import org.springframework.beans.BeanUtils;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.context.SecurityContext;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.security.web.FilterChainProxy;
import org.springframework.security.web.authentication.logout.SecurityContextLogoutHandler;
import org.springframework.security.web.context.HttpSessionSecurityContextRepository;
import org.springframework.security.web.context.SecurityContextRepository;
import org.springframework.web.bind.annotation.*;

import java.util.List;

/**
 * @Author 4040
 * @Date 2025/7/29 9:42
 */
@RestController
@RequiredArgsConstructor
@RequestMapping("user")
@Slf4j
public class UserController {

    private final UserService userService;

    @Operation(summary = "login 登录")
    @PostMapping(value = "/login")
    public Result<UserDto> login(HttpServletRequest request, HttpServletResponse response, @RequestBody LoginQuery loginQuery) {    // 检查请求是否经过 Spring Security 核心过滤器
        // 1. 执行登录逻辑
        UserDto userDto = userService.login(loginQuery);

        // 2. 手动获取当前 SecurityContext
        SecurityContext context = SecurityContextHolder.getContext();

        // 3. 强制写入 Session（核心）
        SecurityContextRepository repository = new HttpSessionSecurityContextRepository();
        repository.saveContext(context, request, response);

        // 4. 验证是否写入成功
        HttpSession session = request.getSession();
        Object securityContext = session.getAttribute(
                HttpSessionSecurityContextRepository.SPRING_SECURITY_CONTEXT_KEY
        );
        System.out.println("手动保存后 Session 中的认证上下文: " + (securityContext != null ? "存在" : "不存在"));

        return Result.success(userDto);
    }

    @Operation(summary = "获取当前登录用户")
    @GetMapping(value = "/current")
    public Result<UserDto> getCurrentUser() {
        UserDto userDto = userService.getCurrentUser();
        return Result.success(userDto);
    }

    @Operation(summary = "logout 注销")
    @PostMapping(value = "/logout")
    public Result<Boolean> logout(Authentication authentication, HttpServletRequest request, HttpServletResponse response) {
        SecurityContextLogoutHandler logoutHandler = new SecurityContextLogoutHandler();
        logoutHandler.logout(request, response, authentication);
        return Result.success(true);
    }

    @Operation(summary = "查询所有用户信息")
    @PostMapping(value = "/list")
    @PreAuthorize("hasAuthority('user::read')")
    public Result<List<UserDto>> list(@RequestParam(required = false) String username,@RequestParam(required = false) String name) {
        LambdaQueryWrapper<User> wrapper = new LambdaQueryWrapper<>();
        wrapper.like(StringUtils.isNotEmpty(username), User::getUsername, username)
                .like(StringUtils.isNotEmpty(name), User::getName, name);
        List<User> userDtoList = userService.list(wrapper);

        return Result.success(userDtoList.stream().map(item -> {
            UserDto userDto = new UserDto();
            BeanUtils.copyProperties(item, userDto);
            return userDto;
        }).toList());
    }

}
